Skip to content

Convert devcontainer to Dockerfile-only build (enables envbuilder cache direct-boot)#32

Draft
bmorton wants to merge 1 commit into
mainfrom
bmorton/devcontainer-dockerfile-only
Draft

Convert devcontainer to Dockerfile-only build (enables envbuilder cache direct-boot)#32
bmorton wants to merge 1 commit into
mainfrom
bmorton/devcontainer-dockerfile-only

Conversation

@bmorton

@bmorton bmorton commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Why

Coder's envbuilder prebuilt-image cache probe (envbuilder_cached_image) cannot reproduce devcontainer feature layers: features install from /.envbuilder/features/... during the build but /tmp/... during the probe, so the probe always misses with uncached RUN command is not supported in cache probe mode and the workspace rebuilds layer-by-layer every start. This is a known, open, version-independent upstream limitation: coder/terraform-provider-envbuilder#68.

A pure-Dockerfile build (no features:) is reproducible by the probe, so a cached workspace can boot directly from the prebuilt image — no build, no layer extraction.

What this does

  • .devcontainer/Dockerfile — installs the entire toolchain via RUN layers, mirroring the previous feature set:
    • Go 1.26.3, Ruby 4.0.5 (ruby-build), Rust stable (rustup), kubectl/helm/minikube, gh, az, sshd (port 2222)
    • npm CLIs: @anthropic-ai/claude-code, @github/copilot, opencode-ai, @openprose/prose-cli
    • unchanged: Namespace nsc, Playwright + Chromium, tmux config
  • .devcontainer/devcontainer.json — removes the features: block and overrideFeatureInstallOrder; keeps remoteUser/containerUser/updateRemoteUserUID/postCreateCommand.
  • Removes devcontainer-lock.json (only relevant to features).
  • README — documents the Dockerfile-only rationale and toolchain.

Validation

I can't build locally (no Docker in my environment), so this is a draft for the Build Containers CI (Dockerfile build + envbuilder + devcontainer up) to validate. Once green and merged, the Cache Devcontainer workflow republishes the cache; then in Coder the envbuilder_cached_image probe should return exists=true and workspaces boot directly from the prebuilt image.

Notes / assumptions to review

  • AI/CLI tools are installed via their npm packages (verified to exist) rather than reproducing each feature's bootstrap/gh-release script — simpler and equivalent. Package→command: @github/copilotcopilot, opencode-aiopencode, @anthropic-ai/claude-codeclaude.
  • Ruby 4.0.5 is compiled via ruby-build (heavier build step than the rest).
  • sshd config is minimal (port 2222); adjust if you rely on the feature's exact setup.
  • This is independent of the cache wiring already merged (cache_repo/workspace_folder template settings stay as-is).

Co-authored-by: Copilot [email protected]

Install the full toolchain (Go, Ruby, Rust, kubectl/helm/minikube, gh, az,
sshd, and the npm CLIs) directly in .devcontainer/Dockerfile instead of via
devcontainer features. Coder's envbuilder cache probe cannot reproduce feature
layers (coder/terraform-provider-envbuilder#68), so a feature-based devcontainer
never hits the prebuilt-image cache and rebuilds every start. A pure-Dockerfile
build is reproducible by the probe, enabling a direct boot from the cached image.

Co-authored-by: Copilot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant